//
// Created by fairy on 2025/2/28 19:26.
//
#ifndef ZQ_CONF_H
#define ZQ_CONF_H
#include<stdint.h>

// ======================兼容GCC======================
#if defined(__ARM__)||defined(SIMULATOR)
// =========== 定义关键字 ===========
#define ioport
#define interrupt
#endif
#if !defined(SIMULATOR)
#define nullptr NULL
#endif

// =========== 属性定义 ===========
#if defined(__ARM__)
#define BYTE_BITS 8 // 一字节的位数，在TMS320C55xx里，这个数为16位
#else
#define BYTE_BITS 16 // 一字节的位数，在TMS320C55xx里，这个数为16位
#endif

// ====================== 辅助宏 ======================
// =========== 静态检查 ===========
#define CONCATENATE_DETAIL(x, y) x##y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define STATIC_ASSERT(pred, msg) \
typedef char CONCATENATE(static_assert_, __LINE__)[(pred) ? 1 : -1]

// =========== 强制内联 ===========
#define ALWAYS_INLINE __attribute__((always_inline))
#define INLINE static inline

namespace hw
{
    // ============================================== 寄存器模板 ===========================================
    template<uint32_t address, typename AddressType, typename DataType>
    class BaseRegister
    {
        static AddressType ptr() { return reinterpret_cast<AddressType>(static_cast<DataType>(address)); }

    public:
        enum{REG = address};
        static void write(DataType val) { *ptr() = val; }

        static void write(const uint16_t shift, const bool val)
        {
            *ptr() = ((*ptr()) & ~(static_cast<DataType>(1) << shift)) | (static_cast<DataType>(val) << shift);
        }

        static DataType read() { return *ptr(); }

        static DataType read(uint16_t shift)
        {
            return ((*ptr()) >> shift) & static_cast<DataType>(1);
        }

        static void clear(const uint16_t shift)
        {
            *ptr() &= ~(static_cast<DataType>(1) << shift);
        }

        static void clear() { *ptr() = 0; }

        static void toggle(const uint16_t shift)
        {
            *ptr() ^= (static_cast<DataType>(1) << shift);
        }

        // 与掩码进行或操作
        static void or_mask(const DataType mask)
        {
            *ptr() |= mask;
        }

        // 根据掩码把相应位置上的值写入寄存器
        static void write_mask(const DataType val,const DataType mask)
        {
            *ptr() = (val & mask) | (*ptr() & (~mask));
        }
    };

    // =============== 模板特化 ==================
    template<uint32_t address, bool Tag>
    class Register
    {
    }; // 主模板

    // 16位寄存器特化
    template<uint32_t address>
    class Register<address, false> : public BaseRegister<address, volatile ioport uint16_t *, uint16_t>
    {
        STATIC_ASSERT(address <= 0xFFFF, "16-bit address overflow");
    };

    // 32位寄存器特化
    template<uint32_t address>
    class Register<address, true> : public BaseRegister<address, unsigned int *, uint32_t>
    {
    };

    // ============================================== 寄存器位域模板 ===========================================
    // 通用位域模板 (width > 1)
    template<uint32_t address, uint16_t width, uint16_t shift, typename AddressType, typename DataType>
    class BaseBitsField
    {
        static AddressType ptr() { return reinterpret_cast<AddressType>(static_cast<DataType>(address)); }

        // 静态检查位域范围
        STATIC_ASSERT(width > 0, "Bit field width must be positive");
        STATIC_ASSERT(shift < sizeof(DataType)*BYTE_BITS, "Shift value too large");
        STATIC_ASSERT((shift + width) <= sizeof(DataType)*BYTE_BITS, "Bit field out of range");
    public:
        enum { MASK = static_cast<DataType>(((1U << width) - 1U) << shift) };
        static void write_bits(uint16_t value)
        {
            *ptr() = (*ptr() & ~MASK) | ((static_cast<DataType>(value) << shift) & MASK);
        }

        static uint16_t read_bits()
        {
            return static_cast<uint16_t>((*ptr() & MASK) >> shift);
        }
    };

    // 单位域特化 (width = 1)
    template<uint32_t address, uint16_t shift, typename AddressType, typename DataType>
    class BaseBitsField<address, 1, shift, AddressType, DataType>
    {
        static AddressType ptr() { return reinterpret_cast<AddressType>(static_cast<DataType>(address)); }

        // 静态检查位移范围
        STATIC_ASSERT(shift < sizeof(DataType)*BYTE_BITS, "Shift value too large");

    public:
        enum { MASK = static_cast<DataType>(1U << shift)};
        static void set() { *ptr() |= (static_cast<DataType>(1) << shift); }
        static void clear() { *ptr() &= ~(static_cast<DataType>(1) << shift); }

        static void write_bit(bool value)
        {
            *ptr() = (*ptr() & ~(static_cast<DataType>(1) << shift)) | (static_cast<DataType>(value) << shift);
        }

        static bool read_bit() { return (*ptr() & (static_cast<DataType>(1) << shift)) != 0; }
        static bool read_bit_not() { return (*ptr() & (static_cast<DataType>(1) << shift)) == 0; }
    };

    // =============== 位域模板特化 ==================
    template<uint32_t address, uint16_t width, uint16_t shift, bool Tag>
    class BitsField
    {
    }; // 主模板

    // 16位寄存器位域特化
    template<uint32_t address, uint16_t width, uint16_t shift>
    class BitsField<address, width, shift, false>
            : public BaseBitsField<address, width, shift, volatile ioport uint16_t *, uint16_t>
    {
    };

    // 32位寄存器位域特化
    template<uint32_t address, uint16_t width, uint16_t shift>
    class BitsField<address, width, shift, true>
            : public BaseBitsField<address, width, shift, unsigned int *, uint32_t>
    {
    };
}

// ====================== MMR寄存器宏 (专用总线访问) ======================
// 声明MMR寄存器（无位域）
#define DECLARE_MMR_REGISTER(REG_NAME, ADDRESS) \
struct REG_NAME : hw::Register<(ADDRESS), false> {};

// 开始声明MMR寄存器（带位域）
#define BEGIN_MMR_REGISTER(REG_NAME, ADDRESS)  struct REG_NAME : hw::Register<(ADDRESS), false>  { enum { REG = ADDRESS};

// 声明MMR寄存器的单位域
#define DECLARE_MMR_BIT(BIT_NAME, SHIFT) \
struct BIT_NAME : hw::BitsField<REG, 1, SHIFT, false> {};

// 声明MMR寄存器的多位域
#define DECLARE_MMR_BITS_FIELD(BITS_NAME, WIDTH, SHIFT) \
struct BITS_NAME : hw::BitsField<REG, WIDTH, SHIFT, false> {};

// 结束MMR寄存器声明
#define END_MMR_REGISTER() };

// ====================== 通用内存访问宏 (标准总线访问) ======================
// 声明通用内存区域（无位域）
#define DECLARE_MEMORY_REGION(REG_NAME, ADDRESS) \
struct REG_NAME : hw::Register<(ADDRESS), true> {};

// 开始声明通用内存区域（带位域）
#define BEGIN_MEMORY_REGION(REG_NAME, ADDRESS) \
struct REG_NAME : hw::Register<(ADDRESS), true> \
{ enum { REG = ADDRESS };

// 声明通用内存区域的单位域
#define DECLARE_MEMORY_BIT(BIT_NAME, SHIFT) \
struct BIT_NAME : hw::BitsField<REG, 1, SHIFT, true> {};

// 声明通用内存区域的多位域
#define DECLARE_MEMORY_BITS_FIELD(BITS_NAME, WIDTH, SHIFT) \
struct BITS_NAME : hw::BitsField<REG, WIDTH, SHIFT, true> {};

// 结束通用内存区域声明
#define END_MEMORY_REGION() };


/**
 *快速定义属性类型
 * @example
 *      DECLARE_ATTRIBUTE(Mode,
 *                  HIZ = 0b00, // TIN/TOUT为高阻态，时钟源是内部CPU时钟源
 *                  OUTPUT = 0b01, // TIN/TOUT为定时器输出，时钟源是内部CPU时钟
 *                  GPIO = 0b10, // TIN/TOUT为通用输出，引脚电平反映的是DATOUT位的值
 *                  EXT_INPUT = 0b11 // TIN/TOUT为定时器输入，时钟源是外部时钟
 *      );
 *      使用方法既可以定义这个类型（模拟enum class)，也可以直接通过NAME来访问。比如
 *          void func(NAME::Type mode);
 *          NAME::Type mode = NAME::Type::HIZ;
**/
#define DECLARE_ATTRIBUTE(NAME, ...) \
struct NAME { \
    typedef enum { \
        __VA_ARGS__ \
    } Type; \
};

#endif //ZQ_CONF_H
